home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Mac100% 1998 November
/
MAC100-1998-11.ISO.7z
/
MAC100-1998-11.ISO
/
オンラインソフト定点観測
/
ユーティリティ
/
Mops 3.2.sea
/
Mops 3.2
/
Mops source
/
PPC source
/
pString
< prev
next >
Wrap
Text File
|
1998-06-17
|
8KB
|
372 lines
¥ String class.
syscall Munger
syscall IUMagString
$ D constant RET ¥ Carriage return character
: $ER
setFwind
cr ." size: " . ." pos: " . ." lim: " .
89 die ;
' $er -> $err
: $= { addr1 len1 addr2 len2 -- }
addr1 addr2 len1 len2 IUMagString
;
: NOPEN ." (not open)" ;
syscall Munger
:class STRING super{ handle } general
record
{ var SIZE
var POS
var LIM
int FLAGS
}
private
:m $err: ¥ called when we find something out of bounds.
." size: " get: size .
." pos: " get: pos .h
." lim: " get: lim .h
89 die
;m
:m $chk:
get: pos 0<
get: lim 0< or
get: pos get: lim u> or
get: lim get: size u> or IF $err: self THEN
;m
public
:m COPYTO: ¥ Redefinition of COPYTO: which will disallow a size change
¥ on the copy. I found it was fairly easy to do this
¥ accidentally, and get into random crash territory.
copyto: super
1 put: flags ;m
:m MARK_ORIGINAL:
¥ Overrides the above check. Marks a copy as original, so we can change its
¥ size. We hope we know what we're doing. At least this is a long name
¥ which could hardly get typed by accident!!
clear: flags ;m
:m HANDLE: ¥ this method returns the handle - replaces get: in super
inline{ ^base @} ;m
:m POS: ¥ ( -- pos )
inline{ get: pos} ;m
:m >POS: ¥ ( newpos -- )
inline{ put: pos} ;m
:m LIM: ¥ ( -- lim )
inline{ get: lim} ;m
:m >LIM: ¥ ( newlim -- )
inline{ put: lim} ;m
:m LEN: ¥ ( -- length )
inline{ get: lim get: pos -} ;m
:m >LEN: ¥ ( newlength -- )
inline{ get: pos + put: lim} ;m
:m SKIP: ¥ ( n -- ) Increments POS by n.
inline{ +: pos} ;m
:m MORE: ¥ ( n -- ) Increments LIM by n.
inline{ +: lim} ;m
:m START: ¥ Sets POS to 0 (the start of the string).
inline{ clear: pos} ;m
:m BEGIN: ¥ Sets POS and LIM to 0, ready to begin some operation.
inline{ clear: pos clear: lim} ;m
:m END: ¥ Sets POS and LIM to the end of the string.
inline{ get: size dup put: pos put: lim} ;m
:m NOLIM: ¥ Sets LIM to the end of the string.
inline{ get: size put: lim} ;m
:m RESET: ¥ Sets POS to 0, and LIM to the end.
inline{ clear: pos get: size put: lim} ;m
:m STEP: ¥ Steps down the string, by setting POS to LIM and
¥ then setting LIM to the end.
inline{ get: lim put: pos get: size put: lim} ;m
:m <STEP: ¥ Backward step. Sets LIM to POS, then POS to 0.
inline{ get: pos put: lim clear: pos} ;m
:m NEW:
0 new: super ¥ allocate a handle of (initially) zero size
clear: size clear: pos clear: lim clear: flags ;m
:m ?NEW:
^base @ nilH <> ?EXIT new: self ;m
:m SIZE: ¥ ( -- size )
inline{ get: size} ;m
:m SETSIZE: ¥ ( newsize -- )
get: flags IF 94 die THEN ¥ Can't do that on a string copy
?new: self
dup setsize: super put: size reset: self ;m
:m CLEAR:
?new: self 0 setsize: self ;m
:m GET: ¥ ( -- addr len ). Gets the active part of the string.
$chk: self
ptr: self get: pos + get: lim get: pos - ;m
:m ALL: ¥ ( -- addr len ) Gets all the string, ignoring POS and LIM.
ptr: self size: self ;m
:m 1ST: ¥ ( -- c ) Returns the char at POS.
inline{ ^base @ @ get: pos + c@} ;m
:m ^1ST: ¥ ( -- addr ) Returns the addr of the char at POS.
inline{ ^base @ @ get: pos +} ;m
private
:m MUNGER: { addr1 len1 addr2 len2 -- offs }
¥ Interface to the Toolbox Munger utility
$chk: self
get: flags IF 94 die THEN ¥ Can't do that on a string copy
^base @
get: pos
addr1 len1 addr2 len2
Munger
size: super put: size ;m
public
:m UC: ¥ ( -- addr len ) Converts string to upper case and gets it.
get: self 2dup upper ;m
:m >UC: ¥ ( -- ) Converts active part of string to upper case
get: self upper ;m
:m PUT: { addr len -- }
¥ Replaces entire string with replacement string. Does NEW:
¥ if not already done.
?new: self clear: pos
0 -1 addr len munger: self put: lim ;m
:m ->: { str ¥ hstate -- }
¥ Replaces self with the active part of string str. We assume
¥ the type, and early bind. As the replacement may cause the
¥ Mem Manager to move things, we lock str for the duration.
str getState: class_as> string -> hstate
str lock: class_as> string
str get: class_as> string put: self
hstate str setState: class_as> string ;m
:m INSERT: { addr len -- }
?new: self
addr 0 addr len munger: self put: pos
len +: lim ;m
:m CHINSERT: ¥ ( c -- ) Inserts the given character.
pad c! pad 1 insert: self ;m
:m $INSERT: { str ¥ hstate -- }
¥ Inserts the active text from the given relocatable
¥ string, using early binding. As the memory manager could
¥ move the source string to make room for the increase in
¥ length of SELF, we lock the source string for the
¥ operation, then restore its previous state.
str getState: class_as> string -> hstate
str lock: class_as> string
str get: class_as> string insert: self
hstate str setState: class_as> string ;m
:m ADD: { addr len -- }
end: self
addr len insert: self ;m
:m $ADD: { str ¥ hstate -- }
str getState: class_as> string -> hstate
str lock: class_as> string
str get: class_as> string add: self
hstate str setState: class_as> string ;m
:m +: ¥ ( char -- ) Appends a char to end of string
pad c! pad 1 add: self ;m
:m OVWR: { addr len -- }
¥ Overwrites the active part of SELF with the string ( addr len ).
¥ Copying stops at the end of the active part, or when len characters
¥ have been transferred. POS is incremented by the number of chars
¥ transferred. This operation is faster than normal replacement, as the
¥ length of SELF cannot change, so Munger is not called.
addr get: self len min dup -> len cmove
len +: pos ;m
:m CHOVWR: ¥ ( c -- ) Overwrites the first char of the active
¥ part of the string ( if any ) by the char c.
get: self IF c! 1 skip: self else 2drop THEN ;m
:m $OVWR: ¥ ( str -- )
get: class_as> string ovwr: self ;m
private
:m (REPL): { len1 addr2 len2 -- }
0 len1 addr2 len2 munger: self put: pos ;m
public
:m REPL: { addr len -- }
len: self addr len (repl): self
get: pos put: lim ;m
:m $REPL: { str ¥ hstate -- }
str getState: string -> hstate
str lock: string
str get: string repl: self
hstate str setState: string ;m
:m DELETE: ¥ Deletes the active part of the string.
¥ LIM is then set equal to POS.
0 0 repl: self ;m
:m DELETEN: { n -- }
¥ From POS, deletes n characters or up to LIM,
¥ whichever comes first. LIM is reduced by the number
¥ of characters deleted.
len: self n min dup -> n
0 0 (repl): self
n negate +: lim ;m
:m PRINT:
nil?: self
IF Nopen ELSE get: self type THEN ;m
¥ :m =: { theobj -- }
¥ ¥ Assigns this string to any object that accepts ( addr len )
¥ get: self put: theobj ;m
:m FILL: ¥ ( c -- )
get: self rot fill ;m
¥ SEARCH: and CHSEARCH: are somewhat interim. Class String+ provides more
¥ efficient versions which also include case handling. But these versions
¥ are short, and may be adequate for many needs.
:m SEARCH: ¥ ( addr len -- b )
0 0 munger: self
dup 0< IF drop false ELSE put: lim true THEN ;m
:m CHSEARCH: ¥ ( c -- b )
pad c! pad 1 search: self ;m
:m <CHSEARCH: { c ¥ strt ^1st addr -- b }
$chk: self
^base @ @ dup -> strt get: pos + -> ^1st
strt get: lim + -> addr
BEGIN
-1 ++> addr
addr ^1st u< IF false EXIT THEN
addr c@ c = IF addr strt - put: pos true EXIT THEN
AGAIN
;m
:m DUMP: { ¥ offs svCurs -- }
nil?: self if Nopen EXIT THEN
curs? -> svCurs -curs
all: self swap .h .h 5 spaces
." pos: " pos: self .h 2 spaces
." lim: " lim: self .h cr
pos: self 5 - 0 max -> offs
all: self swap offs + swap offs - 80 min bounds
DO i c@ bl 126 within?
NIF ret = IF $ A6 ELSE $ D7 THEN
THEN
emit
LOOP cr
pos: self offs - spaces & P emit cr
lim: self offs -
dup 80 < IF spaces & L emit ELSE drop THEN
^1st: self len: self 0 max $ 140 min dump
svCurs -> curs? ;m
:m RD: reset: self dump: self ;m ¥ Handy, and short to type!
;class
endload
¥ =========== the current test block ============
:f TEST { ¥ x -- }
dbgr
cr cr ." hi there one and all!" cr 1 2 3
begin
query cr
begin
rest nip 0>
while
defined?
if execute
else
dbgr
number CDP 1024 - swap dump
then
repeat
.s cr
again
;f
:f quit test ;f ¥ temp so we can catch errors!
endload
+echo
: q db
temp{ string s }
" hello" put: s
dump: s ;